package com.ruoyi.api.controller.moon;


import com.alibaba.fastjson2.JSON;
import com.ruoyi.common.annotation.RepeatSubmit;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.MoonUser;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.enums.UserStatus;
import com.ruoyi.common.utils.MessageUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.ServletUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.framework.web.service.SmsService;
import com.ruoyi.framework.web.service.SysLoginService;
import com.ruoyi.framework.web.service.TokenService;
import com.ruoyi.framework.web.service.WechatService;
import com.ruoyi.framework.wx.WxMiniAppLoginResponseDO;
import com.ruoyi.moon.domain.MoonLeaveMessage;
import com.ruoyi.moon.service.IMoonCompanyService;
import com.ruoyi.moon.service.IMoonLeaveMessageService;
import com.ruoyi.moon.service.IMoonReviewsService;
import com.ruoyi.moon.service.IMoonUserService;
import com.ruoyi.system.service.ISysConfigService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.Random;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@RestController
@RequestMapping("/api/home")
public class ApiMoonController extends BaseController {

    @Autowired
    private TokenService tokenService;
    @Autowired
    private IMoonUserService moonUserService;
    @Autowired
    private SysLoginService loginService;
    @Autowired
    private WechatService wechatService;
    @Autowired
    private IMoonReviewsService moonReviewsService;
    @Autowired
    private IMoonCompanyService moonCompanyService;
    @Autowired
    private SmsService smsService;

    @Autowired
    private RedisCache redisCache;

    @Autowired
    private ISysConfigService configService;

    private final int phoneNumberCount =10;
    private static final Pattern PHONE_PATTERN = Pattern.compile("^1[3-9]\\d{9}$");

    /**
     * 登录方法
     *
     * @param user 登录信息
     * @return 结果
     */
    @RepeatSubmit
    @PostMapping("/login")
    public AjaxResult login(@RequestBody MoonUser user) {
        //微信登录，暂时注释掉
//        if(null != user && StringUtils.isEmpty(user.getOpenId())){
//            MoonUser moonUser = moonUserService.getUserByOpenId(user.getOpenId());
//            if (UserStatus.DELETED.getCode().equals(moonUser.getDelFlag())){
//                return AjaxResult.error(MessageUtils.message("user.blocked"));
//            }
//        }
        if (null == user || StringUtils.isEmpty(user.getPhoneNumber())) {
            return AjaxResult.error("手机号不能为空");
        }
        if (StringUtils.isEmpty(user.getCode()) && StringUtils.isEmpty(user.getPassword())) {
            return AjaxResult.error("验证码或密码不能为空");
        }

        MoonUser u = moonUserService.getUserByPhone(user.getPhoneNumber());
        if (null != u && u.getDelFlag().equals(UserStatus.DISABLE.getCode())){
            return AjaxResult.error("该手机号已被冻结");
        }

        //手机号登录
        if (StringUtils.isNotEmpty(user.getCode())) {
            Object object = redisCache.getCacheObject(user.getPhoneNumber());
            if (ObjectUtils.isEmpty(object)) {
                return AjaxResult.error("验证码已失效");
            }
            if (!object.toString().equals(user.getCode())) {
                return AjaxResult.error("验证码错误");
            }
            //判断当前手机号有没有注册过
            if (null == u) {
                String lastFourDigits = user.getPhoneNumber().substring(user.getPhoneNumber().length() - 4);
                user.setNickName("昵称_" + lastFourDigits);
                String password = configService.selectConfigByKey("sys.user.initPassword");
                user.setPassword(SecurityUtils.encryptPassword(password));
                user.setChannel("PC");
                boolean regFlag = moonUserService.registerUser(user);
                if (!regFlag) {
                    return AjaxResult.error("注册失败,请联系系统管理人员");
                } else {
                    redisCache.deleteObject(user.getPhoneNumber());
                    LoginUser loginUser = new LoginUser();
                    loginUser.setMoonUser(user);
                    loginUser.setUserId(user.getId());
                    AjaxResult ajax = AjaxResult.success();
                    String token = tokenService.createToken(loginUser);
                    ajax.put(Constants.TOKEN, token);
                    return ajax;
                }
            } else {
                //已经注册过，直接登录
                redisCache.deleteObject(user.getPhoneNumber());
                MoonUser moonUser = moonUserService.getUserByPhone(user.getPhoneNumber());
                if (null == moonUser) {
                    return AjaxResult.error(MessageUtils.message("user.not.exists"));
                } else if (UserStatus.DELETED.getCode().equals(moonUser.getDelFlag())) {
                    return AjaxResult.error(MessageUtils.message("user.blocked"));
                }
                LoginUser loginUser = new LoginUser();
                loginUser.setMoonUser(moonUser);
                loginUser.setUserId(moonUser.getId());
                AjaxResult ajax = AjaxResult.success();
                String token = tokenService.createToken(loginUser);
                ajax.put(Constants.TOKEN, token);
                return ajax;
            }
        }
        //密码登录
        MoonUser moonUser = moonUserService.getUserByPhone(user.getPhoneNumber());
        if (null == moonUser) {
            return AjaxResult.error(MessageUtils.message("user.not.exists"));
        } else if (UserStatus.DELETED.getCode().equals(moonUser.getDelFlag())) {
            return AjaxResult.error(MessageUtils.message("user.blocked"));
        }
        if (StringUtils.isNotEmpty(user.getPassword())) {
            //校验密码
            if (!SecurityUtils.matchesPassword(user.getPassword(), moonUser.getPassword())) {
                return AjaxResult.error(MessageUtils.message("user.password.not.match"));
            }
        }

        LoginUser loginUser = new LoginUser();
        loginUser.setMoonUser(moonUser);
        loginUser.setUserId(moonUser.getId());
        AjaxResult ajax = AjaxResult.success();
        String token = tokenService.createToken(loginUser);
        ajax.put(Constants.TOKEN, token);
        return ajax;
    }


    @PostMapping("/phoneCodeLogin")
    public AjaxResult phoneCodeLogin(@RequestBody MoonUser user) {
        if (null == user || StringUtils.isEmpty(user.getPhoneNumber())) {
            return AjaxResult.error("手机号不能为空");
        }
        if (StringUtils.isEmpty(user.getCode())) {
            return AjaxResult.error("验证码或密码不能为空");
        }
        MoonUser u = moonUserService.getUserByPhone(user.getPhoneNumber());
        if (null != u && u.getDelFlag().equals(UserStatus.DISABLE.getCode())) {
            return AjaxResult.error("该手机号已被冻结");
        }
        Object object = redisCache.getCacheObject(user.getPhoneNumber());
        if (ObjectUtils.isEmpty(object)) {
            return AjaxResult.error("验证码已失效");
        }
        if (!object.toString().equals(user.getCode())) {
            return AjaxResult.error("验证码错误");
        }
        //判断当前手机号有没有注册过
        if (null == u) {
            String lastFourDigits = user.getPhoneNumber().substring(user.getPhoneNumber().length() - 4);
            user.setNickName("昵称_" + lastFourDigits);
            user.setImgUrl("/profile/upload/2025/01/09/yxTPvORYQ6Lp9ae74c3620f8f67ef5dd3b58f5d156a4_20250109181729A001.jpg");
            String password = configService.selectConfigByKey("sys.user.initPassword");
            user.setPassword(SecurityUtils.encryptPassword(password));
            user.setChannel("wechat");
            boolean regFlag = moonUserService.registerUser(user);
            if (!regFlag) {
                return AjaxResult.error("注册失败,请联系系统管理人员");
            } else {
                redisCache.deleteObject(user.getPhoneNumber());
                LoginUser loginUser = new LoginUser();
                loginUser.setMoonUser(user);
                loginUser.setUserId(user.getId());
                AjaxResult ajax = AjaxResult.success();
                String token = tokenService.createToken(loginUser);
                ajax.put(Constants.TOKEN, token);
                return ajax;
            }
        } else {
            //已经注册过，直接登录
            redisCache.deleteObject(user.getPhoneNumber());
            MoonUser moonUser = moonUserService.getUserByPhone(user.getPhoneNumber());
            if (null == moonUser) {
                return AjaxResult.error(MessageUtils.message("user.not.exists"));
            } else if (UserStatus.DELETED.getCode().equals(moonUser.getDelFlag())) {
                return AjaxResult.error(MessageUtils.message("user.blocked"));
            }
            LoginUser loginUser = new LoginUser();
            loginUser.setMoonUser(moonUser);
            loginUser.setUserId(moonUser.getId());
            AjaxResult ajax = AjaxResult.success();
            String token = tokenService.createToken(loginUser);
            ajax.put(Constants.TOKEN, token);
            return ajax;
        }
    }

//    @GetMapping("/login/miniProgramLogin")
//    public AjaxResult miniProgramLogin(@RequestParam("code") String code) {
//        AjaxResult ajax = AjaxResult.success();
//        // 生成令牌
//        String token = loginService.miniProgramLogin(code);
//        ajax.put(Constants.TOKEN, token);
//        return ajax;
//    }

    @RepeatSubmit
    @PostMapping("/apiLogin")
    public AjaxResult login(@RequestBody WxMiniAppLoginResponseDO loginRequest) throws Exception {
        return wechatService.getUserInfoMap(loginRequest);
    }

    /**
     * 获取验证码
     *
     * @param phoneNumber
     * @return
     */
    @GetMapping("/getCode")
    public AjaxResult getCode(String phoneNumber) {
        if (StringUtils.isEmpty(phoneNumber)) {
            return AjaxResult.error("手机号不能为空");
        }
        if(!isValidPhoneNumber(phoneNumber)){
            return AjaxResult.error("请输入正确的手机号");
        }
        if (redisCache.hasKey(phoneNumber)) {
            return AjaxResult.error("请勿重复获取");
        }
        MoonUser user = moonUserService.getUserByPhone(phoneNumber);
        if (null != user) {
            if (UserStatus.DISABLE.getCode().equals(user.getDelFlag())) {
                return AjaxResult.error("该手机号已被冻结");
            }
        }
        int count = 0;
        Object object = redisCache.getCacheObject(phoneNumber + "count");
        if(null != object ){
            count = (int)object;
            if(count >= phoneNumberCount){
                return AjaxResult.error("每人每天最多请求10次验证码");
            }
        }
        // 创建一个Random对象
        Random random = new Random();
        // 生成一个1000到9999之间的随机整数
        int captcha = random.nextInt(9000) + 1000;
        String content = "【企业评分网】您的验证码为:"+captcha+"，5分钟内有效。请勿泄露于他人。";
        smsService.smsSend(phoneNumber, content);
        redisCache.setCacheObject(phoneNumber, captcha, 5, TimeUnit.MINUTES);
        //判断距离12点的时间差
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime midnight = now.toLocalDate().plusDays(1).atStartOfDay();
        Duration duration = Duration.between(now, midnight);
        long secondsUntilMidnight = duration.getSeconds();
        redisCache.setCacheObject(phoneNumber+"count", ++count, (int) secondsUntilMidnight, TimeUnit.SECONDS);
        return AjaxResult.success();
    }

    public static boolean isValidPhoneNumber(String phoneNumber) {
        if (phoneNumber == null || phoneNumber.isEmpty()) {
            return false;
        }
        Matcher matcher = PHONE_PATTERN.matcher(phoneNumber);
        return matcher.matches();
    }

    /**
     * 注册获取验证码
     * @param phoneNumber
     * @return
     */
    @GetMapping("/reqGetCode")
    public AjaxResult reqGetCode(String phoneNumber) {
        if (StringUtils.isEmpty(phoneNumber)) {
            return AjaxResult.error("手机号不能为空");
        }
        if(!isValidPhoneNumber(phoneNumber)){
            return AjaxResult.error("请输入正确的手机号");
        }
        if (redisCache.hasKey("req"+phoneNumber)) {
            return AjaxResult.error("请勿重复获取");
        }
        MoonUser user = moonUserService.getUserByPhone(phoneNumber);
        if (null != user) {
            return AjaxResult.error("该手机号已注册");
        }
        int count = 0;
        Object object = redisCache.getCacheObject(phoneNumber + "count");
        if(null != object ){
            count = (int)object;
            if(count >= phoneNumberCount){
                return AjaxResult.error("每人每天最多请求10次验证码");
            }
        }
        // 创建一个Random对象
        Random random = new Random();
        // 生成一个1000到9999之间的随机整数
        int captcha = random.nextInt(9000) + 1000;
        String content = "【企业评分网】您的验证码为:"+captcha+"，5分钟内有效。请勿泄露于他人。";
        smsService.smsSend(phoneNumber, content);
        redisCache.setCacheObject("req"+phoneNumber, captcha, 5, TimeUnit.MINUTES);
        //判断距离12点的时间差
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime midnight = now.toLocalDate().plusDays(1).atStartOfDay();
        Duration duration = Duration.between(now, midnight);
        long secondsUntilMidnight = duration.getSeconds();
        redisCache.setCacheObject(phoneNumber+"count", ++count, (int) secondsUntilMidnight, TimeUnit.SECONDS);
        return AjaxResult.success();
    }
    /**
     * 注册方法
     */
    @PostMapping("/reg")
    public AjaxResult UserReg(@RequestBody MoonUser moonUser) {

        String msg = "";
        MoonUser user = new MoonUser();
        if (StringUtils.isEmpty(moonUser.getPhoneNumber())) {
            return AjaxResult.error("手机号不能为空");
        } else if (StringUtils.isEmpty(moonUser.getPassword())) {
            return AjaxResult.error("密码不能为空");
        } else if (moonUser.getPassword().length() < UserConstants.PASSWORD_MIN_LENGTH
                || moonUser.getPassword().length() > UserConstants.PASSWORD_MAX_LENGTH) {
            return AjaxResult.error("密码长度必须在8到20个字符之间");
        }
        if (StringUtils.isEmpty(moonUser.getCode())) {
            return AjaxResult.error("验证码不能为空");
        }
        Object object = redisCache.getCacheObject("req"+moonUser.getPhoneNumber());
        if (ObjectUtils.isEmpty(object)) {
            return AjaxResult.error("验证码已失效");
        }
        if (!object.toString().equals(moonUser.getCode())) {
            return AjaxResult.error("验证码错误");
        }
        user.setPhoneNumber(moonUser.getPhoneNumber());
        if (!moonUserService.checkUserNameUnique(user)) {
            return AjaxResult.error("手机号已存在");
        }

        String lastFourDigits = moonUser.getPhoneNumber().substring(moonUser.getPhoneNumber().length() - 4);
        moonUser.setNickName("昵称_" + lastFourDigits);
//        moonUser.setImgUrl("https://thirdwx.qlogo.cn/mmopen/vi_32/POgEwh4mIHO4nibH0KlMECNjjGxQUq24ZEaGT4poC6icRiccVGKSyXwibcPq4BWmiaIGuG1icwxaQX6grC9VemZoJ8rg/132");
        moonUser.setImgUrl("/profile/upload/2025/01/09/yxTPvORYQ6Lp9ae74c3620f8f67ef5dd3b58f5d156a4_20250109181729A001.jpg");
        moonUser.setPassword(SecurityUtils.encryptPassword(moonUser.getPassword()));
        moonUser.setChannel("PC");
        boolean regFlag = moonUserService.registerUser(moonUser);
        if (!regFlag) {
            return AjaxResult.error("注册失败,请联系系统管理人员");
        } else {
            redisCache.deleteObject(moonUser.getPhoneNumber());
            LoginUser loginUser = new LoginUser();
            loginUser.setMoonUser(moonUser);
            loginUser.setUserId(moonUser.getId());
            AjaxResult ajax = AjaxResult.success();
            String token = tokenService.createToken(loginUser);
            ajax.put(Constants.TOKEN, token);
            return ajax;
        }
    }


    /**
     * PC端修改密码
     */
    @PostMapping("/changePassword")
    public AjaxResult changePassword(@RequestBody MoonUser moonUser) {

        if (StringUtils.isEmpty(moonUser.getCode())) {
            return AjaxResult.error("验证码不能为空");
        }
        if (StringUtils.isEmpty(moonUser.getPhoneNumber())) {
            return AjaxResult.error("手机号不能为空");
        } else if (StringUtils.isEmpty(moonUser.getPassword())) {
            return AjaxResult.error("密码不能为空");
        } else if (moonUser.getPassword().length() < UserConstants.PASSWORD_MIN_LENGTH
                || moonUser.getPassword().length() > UserConstants.PASSWORD_MAX_LENGTH) {
            return AjaxResult.error("密码长度必须在8到20个字符之间");
        }

        MoonUser user = new MoonUser();
        user.setPhoneNumber(moonUser.getPhoneNumber());
        if (moonUserService.checkUserNameUnique(user)) {
            return AjaxResult.error("手机号不存在");
        }
        Object object = redisCache.getCacheObject(moonUser.getPhoneNumber());
        if (ObjectUtils.isEmpty(object)) {
            return AjaxResult.error("验证码已失效");
        }
        if (!object.toString().equals(moonUser.getCode())) {
            return AjaxResult.error("验证码错误");
        }
        if (!moonUser.getPassword().equals(moonUser.getPasswordGet())) {
            return AjaxResult.error("两次输入的密码不一致");
        }
        moonUser.setPassword(SecurityUtils.encryptPassword(moonUser.getPassword()));
        AjaxResult result = toAjax(moonUserService.changePassword(moonUser));
        if (result.isSuccess()) {
            redisCache.deleteObject(moonUser.getPhoneNumber());
        }
        return result;
    }


    /**
     * 退出登录
     */
    @DeleteMapping("/forceLogout")
    public void forceLogout(HttpServletRequest request, HttpServletResponse response) {
        LoginUser loginUser = tokenService.getLoginUser(request);
        if (StringUtils.isNotNull(loginUser)) {
            // 删除用户缓存记录
            tokenService.delLoginUser(loginUser.getToken());
        }
        ServletUtils.renderString(response, JSON.toJSONString(AjaxResult.success(MessageUtils.message("user.logout.success"))));
    }




    

}